<script lang="jsx">
import componentMinxins from '../ComponentMinxins';
import { defineComponent } from 'vue';
import { parse } from '@vue/compiler-sfc';
//const parseObj = parse(htmlStr)

export default {
	mixins: [componentMinxins],
	name: 'VueContainer',
	components: {},
	props: {
		modelValue: {
			type: [Object, String, Array, Number],
			default: null,
		},
		placeholder: {
			type: String,
			default: '请输入内容',
		},
		template: {
			type: String,
			default: null,
		},
		cpStyle: {
			type: String,
			default: null,
		},
		cpJs: {
			type: String,
			default: null,
		},
	},
	data() {
		return {
			subCompErr: null,
			inputValue: this.modelValue, // 新增一个属性 inputValue
		};
	},
	computed: {
		className() {
			return `vue-contain-${Math.random().toString(16).slice(2)}`;
		},
		scopedStyle() {
			if (this.cpStyle) {
				const scope = `.${this.className}`;
				return this.cpStyle.trim().replace(/(^|\})\s*([^{]+)/g, (m, g1, g2) => {
					return g1 ? `${g1} ${scope} ${g2}` : `${scope} ${g2}`;
				});
			}
			return '';
		},
		component() {
			const result = this.doVueContainerParser((this.cpJs || '').trim(), {});
			const component = result.value;
			if (result.error) {
				result.error = {
					msg: result.error.toString(),
					type: 'js脚本错误',
				};
				return result;
			}
			const template = (this.template || '').replace(/^ *< *template *>|<\/ *template *> *$/g, '').trim();
			// 注入template或render，设定template优先级高于render
			if (template) {
				component.template = template;
				component.render = undefined;
			} else if (!component.render) {
				component.template = '<span>未提供模板或render函数</span>';
			}
			// 注入mixins
			component.mixins = [
				{
					props: {
						mode: {
							type: String,
							default: 'DESIGN',
						},
						modelValue: {
							type: [Object, String, Array, Number],
							default: null,
						},
						required: {
							type: Boolean,
							default: false,
						},
						readonly: {
							type: Boolean,
							default: false,
						},
					},
					mounted() {
						console.log('999', this._value);
					},
					computed: {
						_value: {
							get() {
								return this.modelValue;
							},
							set(val) {
								this.$emit('update:modelValue', val);
							},
						},
					},
					beforeUpdate() {
						this.subCompErr = null;
					},
					emits: ['update:modelValue'],
				},
			];
			return result;
		},
	},
	methods: {
		doVueContainerParser(jsCode, params, globalParams) {
			const NOOP = (args) => args;
			const parser = this.scriptParser(jsCode, NOOP, globalParams);
			const parserFunc = parser.value;
			parser.value = params;
			if (!(parserFunc instanceof Function)) {
				parser.error = new Error('非法的js脚本函数');
			} else {
				try {
					parser.value = parserFunc.call(parserFunc, params);
				} catch (e) {
					parser.error = e;
				}
			}
			return parser;
		},
		scriptParser(jsCode, value, params) {
			const jsParser = { value, error: null };
			try {
				jsParser.value = new Function('context', `return ${jsCode}`)(params) || value;
			} catch (e) {
				jsParser.error = e;
			}
			return jsParser;
		},
	},
	render() {
		const { error: compileErr, value: component } = this.component;
		const error = compileErr || this.subCompErr;
		if (error) {
			return (
				<div class="component-error">
					<div>{error.type}</div>
					<div>{error.msg}</div>
				</div>
			);
		} else {
			const props = { ...this.$attrs, ...this.$props };
			return (
				<div class={this.className}>
					<style>{this.scopedStyle}</style>
					<component
						{...props}
						modelValue={this.inputValue} // 使用 inputValue 替代 _value
						onInput={(e) => (this.inputValue = e)}
						mode={this.mode}
					/>
				</div>
			);
		}
	},
	mounted() {},
	errorCaptured(err, vm, info) {
		this.subCompErr = {
			msg: err && err.toString && err.toString(),
			type: '自定义组件运行时错误：',
		};
	},
	emits: ['update:modelValue'],
};
</script>

<style lang="less" scoped>
.component-error {
	font-size: small;
	color: red;
}
</style>
